package com.twelve.all.nfc;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.provider.Settings;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;

import com.twelve.all.R;
import com.twelve.all.base.BaseActivity;
import com.twelve.all.base.NFCApp;

import java.util.Objects;

/**
 * Created by 张龙臣 on 2020/8/29.
 */

public class BasicActivity extends BaseActivity {
    public static final int REQUEST_WRITE_STORAGE_CODE = 1;
    private boolean mHasNoNfc = false;
    private boolean mInfoExternalNfcDialogWasShown = false;
    private boolean mDonateDialogWasShown = false;
    private Intent mOldIntent = null;

    /**
     * Enable NFC foreground dispatch system.
     */

    /**
     * Disable NFC foreground dispatch system.
     */
    @Override
    public void onPause() {
        NFCApp.disableNfcForegroundDispatch(this);
        super.onPause();
    }

    /**
     * Handle new Intent as a new tag Intent and if the tag/device does not
     */
    @Override//此设备不支持NFC的提示
    public void onNewIntent(Intent intent) {
        int typeCheck = NFCApp.treatAsNewTag(intent, this);
        if (typeCheck == -1 || typeCheck == -2) {
            // Device or tag does not support MIFARE Classic.
            // Run the only thing that is possible: The tag info tool.
            Intent i = new Intent(this, TagInfoTool.class);
            startActivity(i);
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode,
                permissions, grantResults);

        switch (requestCode) {
            case REQUEST_WRITE_STORAGE_CODE:
                if (grantResults.length > 0 &&
                        grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//                    initFolders();
                } else {
                    Toast.makeText(this, "请授权权限",
                            Toast.LENGTH_LONG).show();
                    finish();
//                    enableMenuButtons(false);

                }
                break;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
//        if (NFCApp.hasWritePermissionToExternalStorage(this)) {
//            useAsEditorOnly(NFCApp.useAsEditorOnly());
//            runStartUpNode(StartUpNode.FirstUseDialog);
//        }
    }


    public enum StartUpNode {
        FirstUseDialog, DonateDialog, HasNfc, HasMifareClassicSupport,
        HasNfcEnabled, HasExternalNfc, ExternalNfcServiceRunning,
        HandleNewIntent
    }

    public void runStartUpNode(StartUpNode startUpNode) {
        SharedPreferences sharedPref =
                getPreferences(Context.MODE_PRIVATE);
        SharedPreferences.Editor sharedEditor = sharedPref.edit();
        switch (startUpNode) {
            //第一次调用NFC给个提示
            case FirstUseDialog:
                boolean isFirstRun = sharedPref.getBoolean(
                        "is_first_run", true);
//                if (isFirstRun) {//警告提示
//                    createFirstUseDialog().show();
//                } else {
//                }
                runStartUpNode(StartUpNode.HasNfc);
                break;
            case HasNfc://判断是否有NFC功能
                NFCApp.setNfcAdapter(NfcAdapter.getDefaultAdapter(this));
                if (NFCApp.getNfcAdapter() == null) {
                    mHasNoNfc = true;
                    runStartUpNode(StartUpNode.HasExternalNfc);
                } else {
                    runStartUpNode(StartUpNode.HasMifareClassicSupport);
                }
                break;
            case HasMifareClassicSupport://有NFC功能，判断是否打开
                if (!NFCApp.hasMifareClassicSupport()
                        && !NFCApp.useAsEditorOnly()) {
                    runStartUpNode(StartUpNode.HasExternalNfc);
                } else {
                    runStartUpNode(StartUpNode.HasNfcEnabled);
                }
                break;
            case HasNfcEnabled://NFC没有打开，提示打开
                NFCApp.setNfcAdapter(NfcAdapter.getDefaultAdapter(this));
                if (!NFCApp.getNfcAdapter().isEnabled()) {
                    if (!NFCApp.useAsEditorOnly()) {
                        createNfcEnableDialog().show();
                    } else {
                        runStartUpNode(StartUpNode.DonateDialog);
                    }
                } else {
                    // Use MCT with internal NFC controller.
                    useAsEditorOnly(false);
                    NFCApp.enableNfcForegroundDispatch(this);
                    runStartUpNode(StartUpNode.DonateDialog);
                }
                break;
            case HasExternalNfc:
                if (!NFCApp.hasExternalNfcInstalled(this)
                        && !NFCApp.useAsEditorOnly()) {
                    if (mHasNoNfc) {
                        // Here because the phone is not NFC enabled.
                        createInstallExternalNfcDialog().show();
                    } else {
                        // Here because phone does not support MIFARE Classic.
                        AlertDialog ad = createHasNoMifareClassicSupportDialog();
                        ad.show();
                        // Make links clickable.
                        ((TextView) ad.findViewById(android.R.id.message))
                                .setMovementMethod(
                                        LinkMovementMethod.getInstance());
                    }
                } else {
                    runStartUpNode(StartUpNode.ExternalNfcServiceRunning);
                }
                break;
            case ExternalNfcServiceRunning:
                int isExternalNfcRunning =
                        NFCApp.isExternalNfcServiceRunning(this);
                if (isExternalNfcRunning == 0) {
                    // External NFC is not running.
                    if (!NFCApp.useAsEditorOnly()) {
                        createStartExternalNfcServiceDialog().show();
                    } else {
                        runStartUpNode(StartUpNode.DonateDialog);
                    }
                } else if (isExternalNfcRunning == 1) {
                    // External NFC is running. Use MCT with External NFC.
                    useAsEditorOnly(false);
                    runStartUpNode(StartUpNode.DonateDialog);
                } else {
                    // Can not check if External NFC is running.
                    if (!NFCApp.useAsEditorOnly()
                            && !mInfoExternalNfcDialogWasShown) {
                        createInfoExternalNfcServiceDialog().show();
                        mInfoExternalNfcDialogWasShown = true;
                    } else {
                        runStartUpNode(StartUpNode.DonateDialog);
                    }
                }
                break;
            case DonateDialog:
                if (NFCApp.IS_DONATE_VERSION) {
                    runStartUpNode(StartUpNode.HandleNewIntent);
                    break;
                }
                if (mDonateDialogWasShown) {
                    runStartUpNode(StartUpNode.HandleNewIntent);
                    break;
                }
                int currentVersion = 0;
                try {
                    currentVersion = getPackageManager().getPackageInfo(
                            getPackageName(), 0).versionCode;
                } catch (PackageManager.NameNotFoundException e) {
                    Log.d(this.getClass().getSimpleName(), "Version not found.");
                }
                int lastVersion = sharedPref.getInt("mct_version",
                        currentVersion - 1);
                boolean showDonateDialog = sharedPref.getBoolean(
                        "show_donate_dialog", true);

//                if (lastVersion < currentVersion || showDonateDialog) {
//                    // This is either a new version of MCT or the user
//                    // wants to see the donate dialog.
//                    if (lastVersion < currentVersion) {
//                        // Update the version.
//                        sharedEditor.putInt("mct_version", currentVersion);
//                        sharedEditor.putBoolean("show_donate_dialog", true);
//                        sharedEditor.apply();
//                    }
//                    createDonateDialog().show();
//                    mDonateDialogWasShown = true;
//                } else {
//                }
                mDonateDialogWasShown = true;
                runStartUpNode(StartUpNode.HandleNewIntent);
                break;
            case HandleNewIntent:
                NFCApp.setPendingComponentName(null);
                Intent intent = getIntent();
                if (intent != null) {
                    boolean isIntentWithTag = Objects.equals(intent.getAction(), NfcAdapter.ACTION_TECH_DISCOVERED);
                    if (isIntentWithTag && intent != mOldIntent) {
                        // If MCT was called by another app or the dispatch
                        // system with a tag delivered by intent, handle it as
                        // new tag intent.
                        mOldIntent = intent;
                        onNewIntent(getIntent());
                    } else {
                        // Last node. Do nothing.
                        break;
                    }
                }
                break;
        }
    }

    private void useAsEditorOnly(boolean useAsEditorOnly) {
        NFCApp.setUseAsEditorOnly(useAsEditorOnly);
//        mReadTag.setEnabled(!useAsEditorOnly);
//        mWriteTag.setEnabled(!useAsEditorOnly);
    }

    public AlertDialog createFirstUseDialog() {
        return new AlertDialog.Builder(this)
                .setTitle(R.string.dialog_first_run_title)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setMessage(R.string.dialog_first_run)
                .setPositiveButton(R.string.action_ok,
                        (dialog, which) -> dialog.cancel())
                .setOnCancelListener(
                        dialog -> {
                            SharedPreferences sharedPref =
                                    getPreferences(Context.MODE_PRIVATE);
                            SharedPreferences.Editor sharedEditor = sharedPref.edit();
                            sharedEditor.putBoolean("is_first_run", false);
                            sharedEditor.apply();
                            // Continue with "has NFC" check.
                            runStartUpNode(StartUpNode.HasNfc);
                        })
                .create();
    }

    public AlertDialog createHasNoMifareClassicSupportDialog() {
        CharSequence styledText = Html.fromHtml(
                getString(R.string.dialog_no_mfc_support_device));
        return new AlertDialog.Builder(this)
                .setTitle(R.string.dialog_no_mfc_support_device_title)
                .setMessage(styledText)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setPositiveButton(R.string.action_install_external_nfc,
                        (dialog, which) -> {
                            // Open Google Play for the donate version of MCT.
                            Uri uri = Uri.parse(
                                    "market://details?id=eu.dedb.nfc.service");
                            Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
                            try {
                                startActivity(goToMarket);
                            } catch (ActivityNotFoundException e) {
                                startActivity(new Intent(Intent.ACTION_VIEW,
                                        Uri.parse("https://play.google.com/store"
                                                + "/apps/details?id=eu.dedb.nfc"
                                                + ".service")));
                            }
                        })
                .setNeutralButton(R.string.action_editor_only,
                        (dialog, which) -> {
                            // Only use Editor.
                            useAsEditorOnly(true);
                            runStartUpNode(StartUpNode.DonateDialog);
                        })
                .setNegativeButton(R.string.action_exit_app,
                        (dialog, id) -> {
                            // Exit the App.
                            finish();
                        })
                .setOnCancelListener(
                        dialog -> finish())
                .create();
    }

    /**
     * 打开NFC提示框
     */
    public AlertDialog createNfcEnableDialog() {
        return new AlertDialog.Builder(this)
                .setTitle(R.string.dialog_nfc_not_enabled_title)
                .setMessage(R.string.dialog_nfc_not_enabled)
                .setIcon(android.R.drawable.ic_dialog_info)
                .setPositiveButton(R.string.action_nfc,
                        (dialog, which) -> {
                            // Goto NFC Settings.
                            if (Build.VERSION.SDK_INT >= 16) {
                                startActivity(new Intent(
                                        Settings.ACTION_NFC_SETTINGS));
                            } else {
                                startActivity(new Intent(
                                        Settings.ACTION_WIRELESS_SETTINGS));
                            }
                        })
//                .setNeutralButton(R.string.action_editor_only,
//                        (dialog, which) -> {
//                            // Only use Editor.
//                            useAsEditorOnly(true);
//                            runStartUpNode(StartUpNode.DonateDialog);
//                        })
                .setNegativeButton(R.string.action_exit_app,
                        (dialog, id) -> {
                            // Exit the App.
                            finish();
                        })
                .setOnCancelListener(
                        dialog -> finish())
                .create();
    }

    public AlertDialog createInstallExternalNfcDialog() {
        return new AlertDialog.Builder(this)
                .setTitle(R.string.dialog_no_nfc_support_title)
                .setMessage(R.string.dialog_no_nfc_support)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setPositiveButton(R.string.action_install_external_nfc,
                        (dialog, which) -> {
                            // Open Google Play for the donate version of MCT.
                            Uri uri = Uri.parse(
                                    "market://details?id=eu.dedb.nfc.service");
                            Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
                            try {
                                startActivity(goToMarket);
                            } catch (ActivityNotFoundException e) {
                                startActivity(new Intent(Intent.ACTION_VIEW,
                                        Uri.parse("https://play.google.com/store"
                                                + "/apps/details?id=eu.dedb.nfc"
                                                + ".service")));
                            }
                        })
                .setNeutralButton(R.string.action_editor_only,
                        (dialog, which) -> {
                            // Only use Editor.
                            useAsEditorOnly(true);
                            runStartUpNode(StartUpNode.DonateDialog);
                        })
                .setNegativeButton(R.string.action_exit_app,
                        (dialog, id) -> {
                            // Exit the App.
                            finish();
                        })
                .setOnCancelListener(
                        dialog -> finish())
                .create();
    }

    public AlertDialog createStartExternalNfcServiceDialog() {
        final Context context = this;
        return new AlertDialog.Builder(this)
                .setTitle(R.string.dialog_start_external_nfc_title)
                .setMessage(R.string.dialog_start_external_nfc)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setPositiveButton(R.string.action_start_external_nfc,
                        (dialog, which) -> {
                            useAsEditorOnly(true);
                            NFCApp.openApp(context, "eu.dedb.nfc.service");
                        })
                .setNeutralButton(R.string.action_editor_only,
                        (dialog, which) -> {
                            // Only use Editor.
                            useAsEditorOnly(true);
                            runStartUpNode(StartUpNode.DonateDialog);
                        })
                .setNegativeButton(R.string.action_exit_app,
                        (dialog, id) -> {
                            // Exit the App.
                            finish();
                        })
                .setOnCancelListener(
                        dialog -> finish())
                .create();
    }

    public AlertDialog createInfoExternalNfcServiceDialog() {
        final Context context = this;
        return new AlertDialog.Builder(this)
                .setTitle(R.string.dialog_info_external_nfc_title)
                .setMessage(R.string.dialog_info_external_nfc)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setPositiveButton(R.string.action_external_nfc_is_running,
                        (dialog, which) -> {
                            // External NFC is running. Do "nothing".
                            runStartUpNode(StartUpNode.DonateDialog);
                        })
                .setNeutralButton(R.string.action_start_external_nfc,
                        (dialog, which) -> {
                            NFCApp.openApp(context, "eu.dedb.nfc.service");
                        })
                .setNegativeButton(R.string.action_editor_only,
                        (dialog, id) -> {
                            // Only use Editor.
                            useAsEditorOnly(true);
                            runStartUpNode(StartUpNode.DonateDialog);
                        })
                .setOnCancelListener(
                        dialog -> {
                            // Only use Editor.
                            useAsEditorOnly(true);
                            runStartUpNode(StartUpNode.DonateDialog);
                        })
                .create();
    }

    public AlertDialog createDonateDialog() {
        View dialogLayout = getLayoutInflater().inflate(
                R.layout.dialog_donate,
                findViewById(android.R.id.content), false);
        TextView textView = dialogLayout.findViewById(
                R.id.textViewDonateDialog);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        final CheckBox showDonateDialogCheckBox = dialogLayout
                .findViewById(R.id.checkBoxDonateDialog);
        return new AlertDialog.Builder(this)
                .setTitle(R.string.dialog_donate_title)
                .setIcon(android.R.drawable.ic_dialog_info)
                .setView(dialogLayout)
                .setPositiveButton(R.string.action_ok,
                        (dialog, which) -> dialog.cancel())
                .setOnCancelListener(
                        dialog -> {
                            if (showDonateDialogCheckBox.isChecked()) {
                                // Do not show the donate dialog again.
                                SharedPreferences sharedPref =
                                        getPreferences(Context.MODE_PRIVATE);
                                SharedPreferences.Editor sharedEditor = sharedPref.edit();
                                sharedEditor.putBoolean(
                                        "show_donate_dialog", false);
                                sharedEditor.apply();
                            }
                            runStartUpNode(StartUpNode.HandleNewIntent);
                        })
                .create();
    }
}
